/*
 * IItem.h
 *
 *  Created on: 2010-12-14
 *      Author: Xairy
 */

#ifndef IITEM_H_CALLSTACK
#define IITEM_H_CALLSTACK

#include "Service.h"
#include <e32cmn.h>
#include <e32def.h>
#include <e32std.h>

#define ALIGN_MASK 3
/**
 * 调整为4字节对齐大小
 */
inline TUint16 AlignSize(TUint16 s)
{
    return (s + ALIGN_MASK)&(~ALIGN_MASK);
}

/** 
 *  TItem: 所有可以被压入栈CallStack中的元素必须实现的父类。<br/>
 *        与其说TItem是所有成员的父类，不如说TItem是所有可压如栈中
 *        对象的头部部分。<br/>
 *        实际上, TItem已经考虑到了内存对齐的问题，为4字节
 *  协议：
 *      所有被压入的记录必须在Service中注册类型，同时不能附带任何指针性质的成员
 *      所有的操作空间只限于交换栈中。
 */
class TItem
{
public:
    /**
     * 一段内存上构建一个TItem对象
     *  @param p指向构建对象的指针，该段内存必须能容纳aSize + sizeof(TItem)的对象的大小
     *  @param aType对象对应的具体子类型
     *  @param aSize需要填充的具体对象的字节数
     *  @param aObject对象的内存
     *  @result 构建的内存对象的指针
     *  
     *  @pre p != NULL;
     *       aSize > 0 ;
     *       aObject != NULL;
     *  @post
     *       result->Type() = aType;
     *       result->Size() = aSize + sizeof(TItem);
     */
    static TItem* ConstructItem(TAny* p, EItemType aType, 
                            TUint16 aSize, const TAny* aObject);
    
    inline EItemType Type()const
    {
        return (EItemType)iType;
    }
    
    inline TUint Size()const
    {
        return sizeof(TItem) + iSize;
    }
    
    inline void Copy(TUint8* aDst)const
    {
        __ASSERT_ALWAYS(aDst != NULL, User::Invariant());
        memcpy(aDst, this, sizeof(TItem) + iSize);
    }
    
    TBool Equal(const TItem& aItem)const;
    
protected:
    TItem(EItemType aType)
        :iType(aType)
    {}
    
    TUint16 iType;
    TUint16 iSize;
};

#endif /* IITEM_H_ */
